import hilog from '@ohos.hilog';
import { BaseDataItem } from './DataModels';

// 缓存项接口
interface CacheItem<T> {
  data: T;
  timestamp: number;
  expireTime: number;
}

// 缓存配置接口
interface CacheConfig {
  maxSize: number; // 最大缓存项数量
  defaultExpireTime: number; // 默认过期时间（毫秒）
}

// 缓存管理器类
export class CacheManager {
  private static readonly TAG = 'CacheManager';
  
  // 内存缓存存储
  private memoryCache: Map<string, CacheItem<any>> = new Map();
  
  // 缓存配置
  private config: CacheConfig = {
    maxSize: 100, // 最大缓存100项
    defaultExpireTime: 5 * 60 * 1000 // 默认5分钟过期
  };
  
  // 单例实例
  private static instance: CacheManager;
  
  // 私有构造函数，实现单例模式
  private constructor() {}
  
  /**
   * 获取缓存管理器实例
   * @returns 缓存管理器实例
   */
  static getInstance(): CacheManager {
    if (!CacheManager.instance) {
      CacheManager.instance = new CacheManager();
      hilog.info(0x0000, CacheManager.TAG, '%{public}s', 'CacheManager instance created');
    }
    return CacheManager.instance;
  }
  
  /**
   * 设置缓存配置
   * @param config 缓存配置
   */
  setConfig(config: Partial<CacheConfig>): void {
    this.config = { ...this.config, ...config };
    hilog.info(0x0000, CacheManager.TAG, '%{public}s', `Cache config updated: ${JSON.stringify(this.config)}`);
  }
  
  /**
   * 获取缓存配置
   * @returns 缓存配置
   */
  getConfig(): CacheConfig {
    return { ...this.config };
  }
  
  /**
   * 存储数据到缓存
   * @param key 缓存键
   * @param data 要缓存的数据
   * @param expireTime 过期时间（毫秒），不传则使用默认过期时间
   */
  set<T>(key: string, data: T, expireTime?: number): void {
    // 检查缓存大小，如果超过最大值，清理最旧的缓存项
    if (this.memoryCache.size >= this.config.maxSize) {
      this.evictOldest();
    }
    
    // 创建缓存项
    const cacheItem: CacheItem<T> = {
      data,
      timestamp: Date.now(),
      expireTime: expireTime || this.config.defaultExpireTime
    };
    
    // 存储到缓存
    this.memoryCache.set(key, cacheItem);
    
    hilog.info(0x0000, CacheManager.TAG, '%{public}s', `Cache set for key: ${key}, expires in ${cacheItem.expireTime}ms`);
  }
  
  /**
   * 从缓存获取数据
   * @param key 缓存键
   * @returns 缓存的数据，如果不存在或已过期则返回null
   */
  get<T>(key: string): T | null {
    const cacheItem = this.memoryCache.get(key);
    
    // 如果缓存项不存在
    if (!cacheItem) {
      hilog.debug(0x0000, CacheManager.TAG, '%{public}s', `Cache miss for key: ${key}`);
      return null;
    }
    
    // 检查是否过期
    const now = Date.now();
    if (now - cacheItem.timestamp > cacheItem.expireTime) {
      hilog.debug(0x0000, CacheManager.TAG, '%{public}s', `Cache expired for key: ${key}`);
      this.memoryCache.delete(key);
      return null;
    }
    
    hilog.debug(0x0000, CacheManager.TAG, '%{public}s', `Cache hit for key: ${key}`);
    return cacheItem.data as T;
  }
  
  /**
   * 检查缓存是否存在且未过期
   * @param key 缓存键
   * @returns 是否存在有效缓存
   */
  has(key: string): boolean {
    const cacheItem = this.memoryCache.get(key);
    
    if (!cacheItem) {
      return false;
    }
    
    // 检查是否过期
    const now = Date.now();
    if (now - cacheItem.timestamp > cacheItem.expireTime) {
      this.memoryCache.delete(key);
      return false;
    }
    
    return true;
  }
  
  /**
   * 删除指定缓存项
   * @param key 缓存键
   * @returns 是否成功删除
   */
  delete(key: string): boolean {
    const result = this.memoryCache.delete(key);
    if (result) {
      hilog.info(0x0000, CacheManager.TAG, '%{public}s', `Cache deleted for key: ${key}`);
    }
    return result;
  }
  
  /**
   * 清空所有缓存
   */
  clear(): void {
    const size = this.memoryCache.size;
    this.memoryCache.clear();
    hilog.info(0x0000, CacheManager.TAG, '%{public}s', `Cache cleared, ${size} items removed`);
  }
  
  /**
   * 清理所有过期的缓存项
   * @returns 清理的缓存项数量
   */
  cleanExpired(): number {
    const now = Date.now();
    let cleanedCount = 0;
    
    for (const [key, cacheItem] of this.memoryCache.entries()) {
      if (now - cacheItem.timestamp > cacheItem.expireTime) {
        this.memoryCache.delete(key);
        cleanedCount++;
      }
    }
    
    if (cleanedCount > 0) {
      hilog.info(0x0000, CacheManager.TAG, '%{public}s', `Cleaned ${cleanedCount} expired cache items`);
    }
    
    return cleanedCount;
  }
  
  /**
   * 清理最旧的缓存项
   */
  private evictOldest(): void {
    let oldestKey = '';
    let oldestTime = Number.MAX_VALUE;
    
    for (const [key, cacheItem] of this.memoryCache.entries()) {
      if (cacheItem.timestamp < oldestTime) {
        oldestTime = cacheItem.timestamp;
        oldestKey = key;
      }
    }
    
    if (oldestKey) {
      this.memoryCache.delete(oldestKey);
      hilog.info(0x0000, CacheManager.TAG, '%{public}s', `Evicted oldest cache item: ${oldestKey}`);
    }
  }
  
  /**
   * 获取缓存统计信息
   * @returns 缓存统计信息
   */
  getStats(): { size: number; maxSize: number; hitRate?: number } {
    // 注意：实际应用中可以添加命中率统计
    return {
      size: this.memoryCache.size,
      maxSize: this.config.maxSize,
      hitRate: undefined // 需要额外实现命中率统计
    };
  }
  
  /**
   * 获取所有缓存键
   * @returns 缓存键数组
   */
  keys(): string[] {
    return Array.from(this.memoryCache.keys());
  }
  
  /**
   * 获取缓存项的剩余有效时间（毫秒）
   * @param key 缓存键
   * @returns 剩余有效时间，如果不存在或已过期则返回0
   */
  getRemainingTime(key: string): number {
    const cacheItem = this.memoryCache.get(key);
    
    if (!cacheItem) {
      return 0;
    }
    
    const now = Date.now();
    const elapsed = now - cacheItem.timestamp;
    const remaining = cacheItem.expireTime - elapsed;
    
    return remaining > 0 ? remaining : 0;
  }
}

// 导出单例实例
export const cacheManager = CacheManager.getInstance();